﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Xml.Serialization;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using PhoenixCrabV6.Engine.Images;
using PhoenixCrabV6.Engine.IO;
using PhoenixCrabV6.Engine.IO.Interface;

namespace PhoenixCrabV6.Engine.Screens
{
    [DataContract]
    [KnownType(typeof(SplashScreen))]
    public class GameScreen
    {
        /// <summary>
        /// The image that is displayed on the screen this frame.
        /// Uses Image to store info about any modifications to the display image as well
        /// </summary>
        [XmlIgnore] public Image ScreenDisplay;

        /// <summary>
        /// The path to the XML definition file for this screen
        /// </summary>
        [DataMember]
        public string XmlPath { get; set; }

        [XmlIgnore] public List<ScreenLayer> ScreenLayers { get; private set; }
        
        [XmlIgnore]
        public Type Type
        {
            get { return this.GetType(); }
        }

        protected ContentManager content;

        private static RenderTarget2D renderTarget;

        static RenderTarget2D RenderTarget
        {
            get
            {
                if (renderTarget == null)
                {
                    renderTarget = new RenderTarget2D(ScreenManager.Instance.GraphicsDevice,
                (int)ScreenManager.Instance.DisplayResolution.X, (int)ScreenManager.Instance.DisplayResolution.Y);
                }
                return renderTarget;
            }
        }    
            /*new RenderTarget2D(ScreenManager.Instance.GraphicsDevice,
                (int)ScreenManager.Instance.DisplayResolution.X, (int)ScreenManager.Instance.DisplayResolution.Y);*/

        private static SpriteBatch imageBatch;

        static SpriteBatch ImageBatch
        {
            get
            {
                if (imageBatch == null)
                {
                    imageBatch =  new SpriteBatch(ScreenManager.Instance.GraphicsDevice);
                }
                return imageBatch;
            }
        }

        //TODO Can have different kinds of effects - GameScreenEffect different from ImageEffect

        public GameScreen()
        {
            
            XmlPath = "XML/Screens/" + Type.ToString().Replace("PhoenixCrabV6.Engine.Screens.", "") + ".xml";
        }

        public virtual void LoadContent()
        {
            content = new ContentManager(ScreenManager.Instance.Content.ServiceProvider, "Content");
            if (ScreenLayers == null)
            {
                ScreenLayers = new List<ScreenLayer>();
            }
            ScreenLayers.ForEach(x => x.LoadContent());
        }

        public virtual void UnloadContent()
        {
            content.Unload();
            ScreenLayers.ForEach(x => x.UnloadContent());
        }

        public virtual void Update(GameTime gametime)
        {
            InputManager.Instance.Update();
            ScreenLayers.ForEach(x => x.Update(gametime));

            //TODO Gamescreen should check inputs

            //check the screen layers in a backwards order, topmost first
            for (int i = ScreenLayers.Count - 1; i > 0; i--)
            {
                if (InputManager.Instance.IsClick())
                {
                    var interfacesInLayer = from img in ScreenLayers[i].LayerComponents
                        where img is IInterfaceElement
                        select img;

                    var mousedOver = from l in interfacesInLayer.Cast<IInterfaceElement>()
                        where l.MouseInClickableArea()
                        select l;

                    if (InputManager.Instance.LeftClick())
                    {
                        mousedOver.ToList().ForEach(x => x.LeftClick());
                        break;
                    }

                    if(InputManager.Instance.RightClick())
                    {
                        mousedOver.ToList().ForEach(x => x.RightClick());
                        break;
                    }

                    if (InputManager.Instance.MiddleClick())
                    {
                        mousedOver.ToList().ForEach(x => x.MiddleClick());
                        break;
                    }
                }
            }
            




        }

        public void Draw(SpriteBatch spriteBatch)
        {
            //now we draw the image that we created:
            ScreenDisplay.Draw(spriteBatch);
        }

        public void BackDraw()
        {
            ScreenManager.Instance.GraphicsDevice.SetRenderTarget(renderTarget);
            ScreenManager.Instance.GraphicsDevice.Clear(Color.Transparent);
            ImageBatch.Begin();

            ScreenLayers.ForEach(x => x.Draw(ImageBatch));

            ImageBatch.End();

            //We are rendering this image to a texture, instead of a screen.
            //ScreenDisplay = new Image(renderTarget); //send as a texture2d
            if (ScreenDisplay == null)
            {
                ScreenDisplay = new Image();
            }
            ScreenDisplay.DisplayImage = RenderTarget;
            ScreenManager.Instance.GraphicsDevice.SetRenderTarget(null);
        }

        public static void DrawOnScreenCenter(Texture2D image, SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(image,
                new Vector2((ScreenManager.Instance.DisplayResolution.X - image.Width)/2,
                    (ScreenManager.Instance.DisplayResolution.Y - image.Height)/2), Color.White);
        }
    }
}